home *** CD-ROM | disk | FTP | other *** search
- Subject: v24i072: Purdue tool for students to turn in work, Part02/02
- Newsgroups: comp.sources.unix
- Approved: rsalz@uunet.UU.NET
- X-Checksum-Snefru: e4c1bf89 f82cd38f 3ef584b8 cd1dea8f
-
- Submitted-by: Kevin Braunsdorf <ksb@cc.purdue.edu>
- Posting-number: Volume 24, Issue 72
- Archive-name: pucc-turnin/part02
-
- [ This has some very long lines in it; if your feed chopped them off
- (shame on them!) don't worry about it -- it is only a sample. --r$ ]
-
- #!/bin/sh
- # This is part 02 of pucc-1e
- # ============= turnin.cf/turnin.cf ==============
- if test ! -d 'turnin.cf'; then
- echo 'x - creating directory turnin.cf'
- mkdir 'turnin.cf'
- fi
- if test -f 'turnin.cf/turnin.cf' -a X"$1" != X"-c"; then
- echo 'x - skipping turnin.cf/turnin.cf (File already exists)'
- else
- echo 'x - extracting turnin.cf/turnin.cf (Text)'
- sed 's/^X//' << 'Purdue' > 'turnin.cf/turnin.cf' &&
- # $Id: turnin.cf,v 5.19 90/09/18 15:12:38 ksb Exp $
- # ksb's test line
- test:ksb:submit:system:ALL
- agen231:o1v:submit:agen231:ALL
- agen321:agen321:submit:agen321:ALL
- engr115:siphon:submit:engr115:130tom,330joe
- engr195e:195e:submit:engr195e:wed830,wed930,wed1030,wed1130,wed1230,wed130,wed230,wed330,wed430,thu830,thu930,thu1030,thu1130,thu1230,fri830,fri930,fri1030,fri1130,fri1230,fri130,fri230
- cs110:cvo:submit:cs110:grades
- cs145:w1h:submit:cs145:830mark,1030dan,1130dan,130mark,230dan,330mark
- cs150:xt2:submit:cs150:tagraders,d1s1,d2s1,d2s2,d3s1,d4s1,d4s2,d5s1,d5s2,d6s1,d7s1,d7s2,d8s1,d9s1,d9s2,d10s1,d10s2,d11s1,d12s1,d12s2,d13s1,d14s1,d14s2,d15s1,d15s2,d16s1,d17s1,d17s2,d18s1,d19s1,d19s2,d20s1,d20s2,d21s1,d22s1,d22s2,d23s1,d24s1,d24s2,d25s1
- cs151:cs151:submit:cs151:d0s0
- cs180:wp4:turnin:cs180:930Buster,1030Steve,130Hiralal
- cs181:cs181:submit:cs181:1030rec,1130rec,130rec
- cs250:cs250:fall90:cs250:130,330
- cs251:3ax:project1:cs251:ds1,ds2
- cs352:cs352:submit:cs352:d1s1,d3s1
- cs400:cs440:submit:csusers:ALL
- cs404:1kz:submit:cs404:ALL
- 404hw:cs404:submit:cs404:ALL
- cs413:cs413:submit:csusers:ALL
- cs440:cs440:submit:csusers:930
- cs442:cs442:submit:csusers:830,1130
- cs490a:cs490a:submit:csusers:d1s1,d2s1
- cs502:cs502:proj:csusers:ALL
- cs520:cs520:submit:csusers:ALL
- cs536:cs536ta:submit:cs536t:ALL
- cs543:cs543:submit:csusers:ALL
- cs565:cs565:submit:csusers:ALL
- cs590d:wne:submit:cs590d:ALL
- Purdue
- chmod 0644 turnin.cf/turnin.cf ||
- echo 'restore of turnin.cf/turnin.cf failed'
- Wc_c="`wc -c < 'turnin.cf/turnin.cf'`"
- test 1386 -eq "$Wc_c" ||
- echo 'turnin.cf/turnin.cf: original size 1386, current size' "$Wc_c"
- fi
- # ============= turnin.cf/turnin.cf.5l ==============
- if test -f 'turnin.cf/turnin.cf.5l' -a X"$1" != X"-c"; then
- echo 'x - skipping turnin.cf/turnin.cf.5l (File already exists)'
- else
- echo 'x - extracting turnin.cf/turnin.cf.5l (Text)'
- sed 's/^X//' << 'Purdue' > 'turnin.cf/turnin.cf.5l' &&
- .\"
- .TH TURNIN.CF 5L "PUCC"
- .SH NAME
- turnin.cf \- turnin configuration file format
- .SH DESCRIPTION
- .IR Turnin,
- the electronic submissions program, reads which courses are using turnin,
- which accounts should be sent submissions, what directory to put submitted
- files in for each course, as well as what group the submissions should be
- saved under from a database called `turnin.cf'.
- .PP
- The file turnin.cf consists of a line for each course with the following
- information separated by colons. The course name, the id for the account the
- data should be put into, the subdirectory name in which the data should
- be kept, and the group which should own the files after they have been
- submitted, and a comma separated list of the sections for this course.
- .SH EXAMPLE
- .PP
- A sample turnin configuration file follows:
- .RS
- .nf
- agen231:j1c:submit:agen231:only
- cs180:tt2:turnin:cs180adm:830Bob,930Allan,1030Beth,1230Raghu,330Matt
- cs181:lmt:submit:cs181:1030,1130,130
- cs190k:hpv:submit:cs190k:div1,div2,div3,div4
- cs250:nru:submit:cs250:d1s1,d1s2
- cs251:nnm:submit:cs251:Beaven,Mathur
- cs404:olk:submit:cs404:lab
- cs414:gk3:submit:csusers:mav,lian,jxy
- cs536:cs536ta:submit:cs536t:d1s1,d1s2
- eng115:m2n:submit:eng115:130,230
- test:ksb:submit:system:one,two
- .fi
- .RE
- .SH BUGS
- The superuser must update this file by hand.
- .SH "SEE ALSO"
- turnin(1L), project(1L), turnin(5L), tar(1)
- Purdue
- chmod 0444 turnin.cf/turnin.cf.5l ||
- echo 'restore of turnin.cf/turnin.cf.5l failed'
- Wc_c="`wc -c < 'turnin.cf/turnin.cf.5l'`"
- test 1361 -eq "$Wc_c" ||
- echo 'turnin.cf/turnin.cf.5l: original size 1361, current size' "$Wc_c"
- fi
- # ============= project/install ==============
- if test ! -d 'project'; then
- echo 'x - creating directory project'
- mkdir 'project'
- fi
- if test -f 'project/install' -a X"$1" != X"-c"; then
- echo 'x - skipping project/install (File already exists)'
- else
- echo 'x - extracting project/install (Text)'
- sed 's/^X//' << 'Purdue' > 'project/install' &&
- $ project -i
- project: initialize user tst for a course
- X
- Project allows other users to put files in your account.
- If you do not know what you are doing, stop now.
- Send mail to enroll-info if you have questions or need help.
- X
- Are you sure you want to do this? [ny] y
- X
- Have you ever used project to administer electronic submissions before? [ny] y
- X
- A long name for a course might be something like
- X Programming in Mud
- X
- What is the long name of this course? This is a test
- X
- A short name for a course might be something like
- X cs200
- X
- What is the short name of this course? test
- X
- All submitted files will be under a special subdirectory in your account.
- This directory will be world readable.
- What name would you give the submission directory? [submit]
- X
- The submitted files will not be group readable, but should have an
- appropriate group none the less. For most people the default is fine.
- X
- Which group should the submitted files be in ? [staff] system
- X
- Division/section identifiers separate large classes into
- many smaller parts for grading.
- Examples might be
- X morning
- X afternoon
- Or:
- X d1s1
- X d2s1
- X
- Enter the divisions/sections of your course one per line.
- Use a dot (`.') on a line by itself to stop.
- div/section [d1s1] > one
- div/section [d1s2] > two
- div/section [d1s3] > .
- X
- Lastly, if you would like to be notified by phone when this is done
- Please enter a phone number now: [No, Thanks]
- X
- Mail has been sent to a superuser to finish the configuration.
- You will be contacted via email or telephone when your account
- is ready for use.
- Purdue
- chmod 0444 project/install ||
- echo 'restore of project/install failed'
- Wc_c="`wc -c < 'project/install'`"
- test 1575 -eq "$Wc_c" ||
- echo 'project/install: original size 1575, current size' "$Wc_c"
- fi
- # ============= project/Makefile ==============
- if test -f 'project/Makefile' -a X"$1" != X"-c"; then
- echo 'x - skipping project/Makefile (File already exists)'
- else
- echo 'x - extracting project/Makefile (Text)'
- sed 's/^X//' << 'Purdue' > 'project/Makefile' &&
- # $Id: Makefile,v 4.5 90/10/07 12:55:22 ksb Exp $
- #
- # Makefile for project
- #
- # if you do nat have strcasecmp in libc get it and add it to SRC and OBJ
- # (Berkeley has a free one, mkcat uses that one)
- X
- PROG= project
- BIN= ${DESTDIR}/usr/local/bin
- X
- L=../libopt
- #L=/usr/include/local
- I=/usr/include
- S=/usr/include/sys
- P=
- X
- INCLUDE= -I$L
- DEBUG= -O
- CDEFS=
- CFLAGS= ${DEBUG} ${CDEFS} ${INCLUDE}
- X
- HDR= machine.h
- SRC= project.c
- OBJ= project.o
- #SRC= project.c strcasecmp.c
- #OBJ= project.o strcasecmp.o
- OTHER=
- MAN= project.1l
- SOURCE= Makefile ${HDR} ${SRC} ${MAN} ${OTHER}
- X
- all: ${PROG}
- X
- ${PROG}:$P ${OBJ}
- # ${CC} -o $@ ${CFLAGS} ${OBJ} -lopt
- # ${CC} -o $@ ${CFLAGS} ${OBJ} -L /usr/local/lib -lopt
- X ${CC} -o $@ ${CFLAGS} ${OBJ} ../libopt/libopt.a
- X
- clean: FRC
- X rm -f Makefile.bak ${PROG} *.o a.out core errs tags
- X
- depend: ${HDR} ${SRC} FRC
- X maketd ${CDEFS} ${INCLUDE} ${SRC}
- X
- install: all FRC
- X install -cs ${PROG} ${BIN}/${PROG}
- X
- lint: ${HDR} ${SRC} FRC
- X lint -h ${CDEFS} ${INCLUDE} ${SRC}
- X
- mkcat: ${MAN}
- X mkcat ${MAN}
- X
- print: source FRC
- X lpr -J'${PROG} source' ${SOURCE}
- X
- source: ${SOURCE}
- X
- spotless: clean
- X rcsclean ${SOURCE}
- X
- tags: ${HDR} ${SRC}
- X ctags -t ${HDR} ${SRC}
- X
- ${SOURCE}:
- X co -q $@
- X
- FRC:
- X
- # DO NOT DELETE THIS LINE - maketd DEPENDS ON IT
- X
- project.o: machine.h project.c
- X
- # *** Do not add anything here - It will go away. ***
- Purdue
- chmod 0644 project/Makefile ||
- echo 'restore of project/Makefile failed'
- Wc_c="`wc -c < 'project/Makefile'`"
- test 1326 -eq "$Wc_c" ||
- echo 'project/Makefile: original size 1326, current size' "$Wc_c"
- fi
- # ============= turnin.cf/Makefile ==============
- if test -f 'turnin.cf/Makefile' -a X"$1" != X"-c"; then
- echo 'x - skipping turnin.cf/Makefile (File already exists)'
- else
- echo 'x - extracting turnin.cf/Makefile (Text)'
- sed 's/^X//' << 'Purdue' > 'turnin.cf/Makefile' &&
- # $Id: Makefile,v 4.1 90/11/28 12:42:14 ksb Exp $
- #
- # Makefile for turnin.cf
- #
- X
- PROG= turnin.cf
- LIB= ${DESTDIR}/usr/local/lib
- X
- SRCl= turnin.cf
- SRCs=
- MAN= turnin.5l turnin.cf.5l
- OTHER= Distfile
- SOURCE= Makefile ${SRCl} ${SRCs} ${MAN} ${OTHER}
- X
- all: ${SRCl} ${PROG}
- X
- clean: FRC
- X rm -f Makefile.bak *.o a.out core errs tags
- X
- deinstall: ${MAN}
- X install -R ${LIB}/${PROG}
- X mkcat -D ${MAN}
- X
- depend: FRC
- X
- install: all FRC
- X install -cm 644 ${SRCl} ${LIB}
- X distrib -a Distfile
- X
- lint: FRC
- X
- mkcat: ${MAN}
- X mkcat ${MAN}
- X
- print: source FRC
- X lpr -J'${PROG} source' ${SOURCE}
- X
- source: ${SOURCE}
- X
- spotless: clean
- X rcsclean ${SOURCE}
- X
- tags: FRC
- X
- ${SOURCE}:
- X co -q $@
- X
- FRC:
- X
- # DO NOT DELETE THIS LINE - make depend DEPENDS ON IT
- X
- # *** Do not add anything here - It will go away. ***
- Purdue
- chmod 0644 turnin.cf/Makefile ||
- echo 'restore of turnin.cf/Makefile failed'
- Wc_c="`wc -c < 'turnin.cf/Makefile'`"
- test 767 -eq "$Wc_c" ||
- echo 'turnin.cf/Makefile: original size 767, current size' "$Wc_c"
- fi
- # ============= turnin.cf/ckcf.sh ==============
- if test -f 'turnin.cf/ckcf.sh' -a X"$1" != X"-c"; then
- echo 'x - skipping turnin.cf/ckcf.sh (File already exists)'
- else
- echo 'x - extracting turnin.cf/ckcf.sh (Text)'
- sed 's/^X//' << 'Purdue' > 'turnin.cf/ckcf.sh' &&
- #!/bin/sh
- X
- BASE=${1-turnin.cf}
- X
- grep -v '#' < $BASE | awk -F: '{ print $4 }' |
- while read group
- do
- X grep "^$group:" /etc/group >/dev/null && continue
- X echo "$0: $BASE: $group: no such group"
- done
- X
- grep -v '#' < $BASE | awk -F: '{ print $2 }' |
- while read user
- do
- X grep "^$user:" /etc/passwd >/dev/null && continue
- X echo "$0: $BASE: $user: no such user"
- done
- X
- Xexit 0
- Purdue
- chmod 0644 turnin.cf/ckcf.sh ||
- echo 'restore of turnin.cf/ckcf.sh failed'
- Wc_c="`wc -c < 'turnin.cf/ckcf.sh'`"
- test 366 -eq "$Wc_c" ||
- echo 'turnin.cf/ckcf.sh: original size 366, current size' "$Wc_c"
- fi
- # ============= turnin.cf/Distfile ==============
- if test -f 'turnin.cf/Distfile' -a X"$1" != X"-c"; then
- echo 'x - skipping turnin.cf/Distfile (File already exists)'
- else
- echo 'x - extracting turnin.cf/Distfile (Text)'
- sed 's/^X//' << 'Purdue' > 'turnin.cf/Distfile' &&
- #
- # $Header: /usr/msrc/vax/local/lib/turnin.cf/RCS/Distfile,v 4.0 90/01/13 12:02:14 ksb Exp $
- #
- X
- ( /usr/local/lib/turnin.cf ) -> ( HOST )
- X install ;
- Purdue
- chmod 0444 turnin.cf/Distfile ||
- echo 'restore of turnin.cf/Distfile failed'
- Wc_c="`wc -c < 'turnin.cf/Distfile'`"
- test 149 -eq "$Wc_c" ||
- echo 'turnin.cf/Distfile: original size 149, current size' "$Wc_c"
- fi
- # ============= project/project.c ==============
- if test -f 'project/project.c' -a X"$1" != X"-c"; then
- echo 'x - skipping project/project.c (File already exists)'
- else
- echo 'x - extracting project/project.c (Text)'
- sed 's/^X//' << 'Purdue' > 'project/project.c' &&
- /*
- X * project -- reads the turnin database to determin what directory (ksb)
- X * it should build a turnin(1l) directory tree for the given course
- X * in. Then reads a local database for a list of dXsY directories
- X * to build.
- X *
- X * project [-dehiorvV] [-c course] [-G cmd] [-g cmd] [number|name]
- X *
- X * $Compile: ${cc-cc} ${cc_debug--O} -I/usr/include/local %f -o %F -lopt
- X */
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/file.h>
- #include <sys/param.h>
- #ifdef pdp11
- #include <ndir.h>
- #else /* VAX */
- #include <sys/dir.h>
- #include <sys/time.h>
- #include <sys/resource.h>
- #endif
- #include <pwd.h>
- #include <grp.h>
- #include <stdio.h>
- #include <ctype.h>
- #include <errno.h>
- extern int errno;
- extern char *sys_errlist[];
- #define strerror(Me) (sys_errlist[Me])
- extern int pclose(), fclose();
- X
- #include "getopt.h"
- #include "machine.h"
- X
- #if HAVE_STRINGS
- #include <strings.h>
- #else
- #include <string.h>
- #endif
- X
- #if USE_LOCKF
- #include <unistd.h>
- #endif
- X
- extern FILE *popen();
- extern char *malloc(), *strchr(), *strrchr();
- #define strsave(Mpch) strcpy(malloc(strlen(Mpch)+1), Mpch)
- X
- static char RCSId[] =
- X "$Id: project.c,v 4.9 90/09/04 08:33:35 ksb Exp $";
- X
- typedef enum {
- X ON,
- X OFF,
- X DELETE
- } STATUS;
- X
- static STATUS Projstatus[MAXPROJECTS];
- X
- typedef enum {
- X DISABLE, /* submissions off */
- X ENABLE, /* submissions on for project */
- X HELP, /* need help */
- X INITIALIZE, /* set up the intructors account */
- X OUTPUT, /* display status */
- X QUIT, /* stop using project, request del */
- X REMOVE, /* delete submissions for proj */
- X GRADE, /* scan directories for tar file */
- X LATE, /* enable late submissions */
- X VERSION, /* show version of project running */
- X UNKNOWN /* we were not told */
- } WHAT;
- X
- static WHAT What; /* what am I doing */
- X
- static int
- X fExec = 1, /* do commands */
- X fVerbose = 0, /* print shell cmds */
- X iProjnum = -1, /* default project */
- X iProjcount = 0; /* number of projects */
- X
- static struct passwd
- X *ppwMe; /* more deatails about the owner */
- X
- static char
- X acMd[MAXDIVSEC+1], /* %d div/sec as in (dXsX) */
- X acMp[MAXPROJNAME+1], /* %p the project number */
- X acMu[MAXLOGINNAME+1], /* %u uid of student */
- X aacProjnames[MAXPROJNAME+1][MAXPROJECTS],
- X /* names of projects */
- X *progname = /* name we run under */
- X RCSId,
- X *pcSum, /* command per division */
- X *pcCmd; /* command to unpack */
- X
- static char
- X acLine[MAXCHARS], /* all these point in here */
- X *pcCourse, /* who */
- X *pcUid, /* who -> uid */
- X *pcDir, /* who -> where */
- X *pcGroup, /* who -> group */
- X *pcSections, /* who -> sections */
- X acSubmit[] = "submit", /* default turnin directory */
- X acLock[] = LOCKFILE, /* keep lock a file, many projects loose*/
- X acMailAddr[] = MAILTO, /* sys admin's address */
- X acSectIgnore[] = /* section that means ``none given'' */
- X SECTIGNORE,
- X acTurnbase[] = /* data base of project co-ordinators */
- X TURNBASE,
- X acDeadLetter[] = /* maildrop for dead mail */
- X "dead.letter";
- X
- X
- /*
- X * reads a configuration file of the form: (doc/ksb)
- X * course:alpha login:subdir for this course:alpha gid:sections\n
- X */
- int
- getcourse(pcBase)
- char *pcBase;
- {
- X register FILE *fpDB;
- X register char *pc;
- X register int line;
- X register char *pcMaybe;
- X static char acError[] = "%s: %s(%d): error in data base\n";
- X
- X if (0 == (fpDB = fopen(pcBase, "r"))) {
- X fprintf(stderr, "%s: fopen: %s: %s\n", progname, pcBase, strerror(errno));
- X exit(errno);
- X }
- X
- X line = 0;
- X while (NULL != fgets(acLine, MAXCHARS, fpDB)) {
- X ++line;
- X pcMaybe = acLine;
- X while (isspace(*pcMaybe) && '\n' != *pcMaybe)
- X ++pcMaybe;
- X if ('#' == *pcMaybe || '\n' == *pcMaybe)
- X continue;
- X if (NULL == (pc = strchr(acLine, SEP))) {
- X fprintf(stdout, acError, progname, pcBase, line);
- X exit(16);
- X }
- X *pc++ = '\000';
- X pcUid = pc;
- X if (NULL == (pc = strchr(pc, SEP))) {
- X fprintf(stdout, acError, progname, pcBase, line);
- X exit(17);
- X }
- X *pc++ = '\000';
- X pcDir = pc;
- X if (NULL == (pc = strchr(pc, SEP))) {
- X fprintf(stdout, acError, progname, pcBase, line);
- X exit(18);
- X }
- X *pc++ = '\000';
- X pcGroup = pc;
- X if (NULL == (pc = strchr(pc, SEP))) {
- X fprintf(stdout, acError, progname, pcBase, line);
- X exit(19);
- X }
- X *pc++ = '\000';
- X pcSections = pc;
- X if (NULL != (pc = strchr(pc, '\n'))) {
- X *pc = '\000';
- X }
- X if ((char *)0 != pcCourse && 0 == strcmp(pcCourse, pcMaybe)) {
- X return 1;
- X }
- X if ((char *)0 == pcCourse && 0 == strcmp(pcUid, ppwMe->pw_name)) {
- X pcCourse = pcMaybe;
- X return 1;
- X }
- X }
- X return 0;
- }
- X
- /*
- X * get the cmdline options
- X */
- static void
- options(argc, argv)
- register int argc;
- register char **argv;
- {
- X static char acOpts[] = "c:dehinorvVlqg:G:";
- X static char acTwo[] = "%s: %s: more than one task given\n";
- X register int n;
- X
- X What = UNKNOWN;
- X while (EOF != (n = getopt(argc, argv, acOpts))) {
- X switch (n) {
- X case 'c':
- X pcCourse = optarg;
- X break;
- X case 'd':
- X if (UNKNOWN != What) {
- X fprintf(stderr, acTwo, progname, "disable");
- X exit(1);
- X }
- X What = DISABLE;
- X break;
- X case 'e':
- X if (UNKNOWN != What) {
- X fprintf(stderr, acTwo, progname, "enable");
- X exit(1);
- X }
- X What = ENABLE;
- X break;
- X case 'G':
- X if (UNKNOWN != What && GRADE != What) {
- X fprintf(stderr, acTwo, progname, "grade");
- X exit(1);
- X }
- X if ((char *)0 != pcSum) {
- X fprintf(stderr, "%s: grade: two commands given for `G\'\n", progname);
- X exit(1);
- X }
- X What = GRADE;
- X pcSum = optarg;
- X break;
- X case 'g':
- X if (UNKNOWN != What && GRADE != What) {
- X fprintf(stderr, acTwo, progname, "grade");
- X exit(1);
- X }
- X if ((char *)0 != pcCmd) {
- X fprintf(stderr, "%s: grade: two commands given for `g\'\n", progname);
- X exit(1);
- X }
- X What = GRADE;
- X pcCmd = optarg;
- X break;
- X case 'l':
- X if (UNKNOWN != What) {
- X fprintf(stderr, acTwo, progname, "late");
- X exit(1);
- X }
- X What = LATE;
- X break;
- X case 'h':
- X if (UNKNOWN != What) {
- X fprintf(stderr, acTwo, progname, "help");
- X exit(1);
- X }
- X What = HELP;
- X break;
- X case 'i':
- X if (UNKNOWN != What) {
- X fprintf(stderr, acTwo, progname, "initialize");
- X exit(1);
- X }
- X What = INITIALIZE;
- X break;
- X case 'o':
- X if (UNKNOWN != What) {
- X fprintf(stderr, acTwo, progname, "output");
- X exit(1);
- X }
- X What = OUTPUT;
- X break;
- X case 'n':
- X fExec = 0;
- X break;
- X case 'V':
- X if (UNKNOWN != What) {
- X fprintf(stderr, acTwo, progname, "version");
- X exit(1);
- X }
- X What = VERSION;
- X break;
- X case 'v':
- X fVerbose = 1;
- X break;
- X case 'q':
- X if (UNKNOWN != What) {
- X fprintf(stderr, acTwo, progname, "quit");
- X exit(1);
- X }
- X What = QUIT;
- X break;
- X case 'r':
- X if (UNKNOWN != What) {
- X fprintf(stderr, acTwo, progname, "remove");
- X exit(1);
- X }
- X What = REMOVE;
- X break;
- X default:
- X break;
- X }
- X }
- }
- X
- /*
- X * remove the trailing newline from a fgets'd input line (ray)
- X */
- static void
- fixup(string)
- register char *string;
- {
- X char *newline;
- X
- X if (NULL != (newline = strchr(string, '\n'))) {
- X *newline = '\000';
- X }
- }
- X
- static char acProjlist[] = /* path to project list */
- X PROJLIST;
- X
- /*
- X * check for illegal chars in project name (ksb)
- X */
- void
- CheckChars(pcFrom, pcProj)
- char *pcFrom, *pcProj;
- {
- X if ('\000' == *pcProj) {
- X fprintf(stderr, "%s: empty project name given %s\n", progname, pcFrom);
- X exit(8);
- X }
- X do {
- X switch (*pcProj) {
- X case '/':
- X case '.':
- X fprintf(stderr, "%s: project name given %s cannot contain `%c\'.\n", progname, pcFrom, *pcProj);
- X exit(8);
- X default:
- X break;
- X }
- X } while ('\000' != *++pcProj);
- }
- X
- X
- /*
- X * open projlist & read it (ksb)
- X */
- int
- getprojects()
- {
- X register FILE *fp;
- X auto int status;
- X auto int proj;
- X
- X if (NULL == (fp = fopen(acProjlist, "r"))) {
- X if (fExec) {
- X if (NULL == (fp = fopen(acProjlist, "w"))) {
- X fprintf(stderr, "%s: fopen: %s: %s\n", progname, acProjlist, strerror(errno));
- X exit(errno);
- X }
- X fclose(fp);
- X }
- X iProjcount = 0;
- X return;
- X }
- X proj = 0;
- X while (EOF != (status = getc(fp))) {
- X switch(status) {
- X case '-':
- X fgets(aacProjnames[proj], MAXCHARS, fp);
- X Projstatus[proj] = OFF;
- X break;
- X case '+':
- X fgets(aacProjnames[proj], MAXCHARS, fp);
- X Projstatus[proj] = ON;
- X break;
- X case '=':
- X fgets(aacProjnames[proj], MAXCHARS, fp);
- X Projstatus[proj] = ON;
- X iProjnum = proj;
- X break;
- X default:
- X fprintf(stderr, "%s: `%s\' is hosed\n", progname, acProjlist);
- X exit(20);
- X break;
- X }
- X fixup(aacProjnames[proj]);
- X CheckChars("in `Projlist\'", aacProjnames[proj]);
- X proj++;
- X }
- X iProjcount = proj;
- X fclose(fp);
- }
- X
- /*
- X * find a project in the in-core database (ksb)
- X */
- int
- search(name)
- register char *name;
- {
- X int i;
- X
- X for (i = 0; i < iProjcount; ++i) {
- X if (0 == strcasecmp(name, aacProjnames[i])) {
- X return i;
- X }
- X }
- X
- X ++iProjcount;
- X Projstatus[i] = ON;
- X strcpy(aacProjnames[i], name);
- X return i;
- }
- X
- /*
- X * update the PROJLIST file (doc/ksb)
- X */
- static void
- newprojects(fWarn)
- int fWarn; /* warn of no default project. */
- {
- X register FILE *fp;
- X register int projout;
- X register int flag1 = 0;
- X register int flag2 = 0;
- X
- X if (fExec) {
- X if (NULL == (fp = fopen(acProjlist, "w"))) {
- X fprintf(stderr, "%s: fopen: %s: %s\n", progname, acProjlist, strerror(errno));
- X exit(1);
- X }
- X }
- X
- X for (projout = 0; projout < iProjcount; projout++) {
- X if (Projstatus[projout] != DELETE) {
- X if (fExec) {
- X fprintf(fp, "%c%s\n",
- X Projstatus[projout] == OFF ? '-' :
- X iProjnum == projout ? '=' : '+',
- X aacProjnames[projout]);
- X }
- X if (fVerbose) {
- X fprintf(stdout, "echo %c%s %s %s\n",
- X Projstatus[projout] == OFF ? '-' :
- X iProjnum == projout ? '=' : '+',
- X aacProjnames[projout],
- X flag2 == 0 ? ">" : ">>",
- X acProjlist);
- X flag2 = 1;
- X }
- X if (projout == iProjnum && Projstatus[projout] == ON) {
- X flag1 = 1;
- X }
- X }
- X }
- X if (fExec) {
- X fclose(fp);
- X }
- X if (flag1 == 0 && fWarn) {
- X fprintf(stderr, "%s: no default project\n", progname);
- X }
- }
- X
- /*
- X * chdir to the argument, create it if you can't find it (ksb)
- X */
- static void
- ceedee(pcMove)
- char *pcMove;
- {
- X if (0 != chdir(pcMove)) {
- X if (fExec) {
- X if (0 != mkdir(pcMove, 0755) || 0 != chdir(pcMove)) {
- X fprintf(stderr, "%s: chdir: %s: %s\n", progname, pcMove, strerror(errno));
- X exit(1);
- X }
- X }
- X if (fVerbose) {
- X fprintf(stdout, "mkdir %s\n", pcMove);
- X }
- X }
- X if (fVerbose) {
- X fprintf(stdout, "cd %s\n", pcMove);
- X }
- }
- X
- /*
- X * you don't want to look at thew next four blocks (ksb)
- X */
- static char acComma[] = ",.";
- static char *_pc = acComma+1;
- X
- static void
- trav_init()
- {
- X _pc = pcSections;
- }
- X
- static int
- traverse(pcBuf)
- char *pcBuf;
- {
- X extern char *strchr();
- X register char *p;
- X
- X if (_pc == acComma+1)
- X return 0;
- X
- X if ((char *)0 == (p = strchr(_pc, ','))) {
- X p = acComma;
- X }
- X *p = '\000';
- X strcpy(pcBuf, _pc);
- X *p = ',';
- X _pc = p+1;
- X
- X return 1;
- }
- X
- /*
- X * close off traverse
- X */
- static void
- travisty()
- {
- X ;
- }
- X
- /*
- X * get the file lock for us (ksb)
- X */
- int
- OpenLock()
- {
- X auto int fdLock;
- X
- X if (-1 == (fdLock = open(acLock, O_RDWR|O_CREAT, 0600))) {
- X fprintf(stderr, "%s: open: %s: %s\n", progname, acLock, strerror(errno));
- X exit(1);
- X }
- X
- #if USE_LOCKF
- X if (lockf(fdLock, F_TLOCK, 0) == -1) {
- X if (errno == EAGAIN || errno == EACCES) {
- X fprintf(stderr, "%s: waiting for lock\n", progname);
- X if (lockf(fdLock, F_LOCK, 0) == -1) {
- X goto bad_lock;
- X }
- X fprintf(stderr, "%s: got lock\n", progname);
- X } else {
- X bad_lock:
- X fprintf(stderr, "%s: lockf: %s\n", progname, strerror(errno));
- X exit(2);
- X }
- X }
- #else
- X if (-1 == flock(fdLock, LOCK_NB|LOCK_EX)) {
- X if (EWOULDBLOCK == errno) {
- X fprintf(stderr, "%s: waiting for lock\n", progname);
- X if (-1 == flock(fdLock, LOCK_EX)) {
- X goto bad_lock;
- X }
- X fprintf(stderr, "%s: got lock\n", progname);
- X } else {
- X bad_lock:
- X fprintf(stderr, "%s: flock: %s\n", progname, strerror(errno));
- X exit(1);
- X }
- X }
- #endif
- X
- #if defined(F_SETFD)
- X if (-1 == fcntl(fdLock, F_SETFD, 1)) {
- X fprintf(stderr, "%s: fcntl: %s (ignored)\n", progname, strerror(errno));
- X }
- #endif
- X return fdLock;
- }
- X
- /*
- X * make the project tree (if it doesn't exist) (ksb)
- X */
- static void
- Make(pcProj)
- char *pcProj;
- {
- X auto char acDivSec[MAXDIVSEC];
- X
- X ceedee(pcProj);
- X if (0 != strcmp(acSectIgnore, pcSections)) {
- X trav_init();
- X while (traverse(acDivSec)) {
- X if (fVerbose) {
- X fprintf(stdout, "mkdir %s\n", acDivSec);
- X }
- X if (!fExec) {
- X continue;
- X }
- X if (0 != mkdir(acDivSec, 0755) && EEXIST != errno) {
- X fprintf(stderr, "%s: mkdir: %s\n", progname, strerror(errno));
- X exit(2);
- X }
- X }
- X travisty();
- X }
- X ceedee("..");
- }
- X
- /*
- X * fork off a UNIX rm to recursively remove unloved files (ksb)
- X */
- static void
- rm(pcFile)
- char *pcFile;
- {
- X if (fVerbose) {
- X fprintf(stdout, "rm -rf %s\n", pcFile);
- X }
- X if (fExec) {
- X if (0 == fork()) {
- X execl("/bin/rm", "rm", "-rf", pcFile, 0);
- X fprintf(stderr, "%s: execl: /bin/rm: %s\n", progname, strerror(errno));
- X exit(1);
- X }
- X wait(0);
- X }
- }
- X
- /*
- X * remove the dir struct for a project with some rm's (ksb)
- X */
- static void
- Remove(pcProj)
- char *pcProj;
- {
- X auto char acDivSec[MAXDIVSEC];
- X
- X if (0 != chdir(pcProj)) { /* no exist, don't make */
- X return;
- X }
- X chdir("..");
- X ceedee(pcProj); /* for verbose mode */
- X if (0 != strcmp(acSectIgnore, pcSections)) {
- X trav_init();
- X while (traverse(acDivSec)) {
- X rm(acDivSec);
- X }
- X travisty();
- X }
- X ceedee("..");
- X rm(pcProj);
- }
- X
- /*
- X * like strcat, but return value is end of string (doc)
- X */
- static char *
- stradd(pcTo, pcFrom)
- register char *pcFrom, *pcTo;
- {
- X while (*pcTo = *pcFrom++)
- X ++pcTo;
- X return pcTo;
- }
- X
- /*
- X * using the global state, produce a shell cammand an system it off (ksb)
- X *
- X * escapse in command:
- X * %u uid of student
- X * %d division/section is (dXsX)
- X * %p the project number
- X * %t submissions directory
- X * %h home of grader
- X * %s full path %h/%t/%p/%d/%u
- X * %% a %
- X */
- static void
- grade(pcFrom)
- register char *pcFrom;
- {
- X static char *pcExec = (char *)0;
- X register char *pcTo;
- X
- X if ((char *)0 == pcExec) {
- X pcExec = malloc(NCARGS);
- X if ((char *)0 == pcExec) {
- X fprintf(stderr, "%s: out of memory\n", progname);
- X exit(errno);
- X }
- X }
- X pcTo = pcExec;
- X while ('\000' != pcFrom[0]) {
- X if ('%' == pcFrom[0]) {
- X ++pcFrom;
- X switch (*pcFrom++) {
- X case '%':
- X *pcTo++ = '%';
- X continue;
- X case 'u':
- X pcTo = stradd(pcTo, acMu);
- X break;
- X case 'd':
- X pcTo = stradd(pcTo, acMd);
- X break;
- X case 'p':
- X pcTo = stradd(pcTo, acMp);
- X break;
- X case 't':
- X pcTo = stradd(pcTo, pcDir);
- X break;
- X case 'h':
- X pcTo = stradd(pcTo, ppwMe->pw_dir);
- X break;
- X case 's':
- X pcTo = stradd(pcTo, ppwMe->pw_dir);
- X *pcTo++ = '/';
- X pcTo = stradd(pcTo, pcDir);
- X *pcTo++ = '/';
- X pcTo = stradd(pcTo, acMp);
- X *pcTo++ = '/';
- X pcTo = stradd(pcTo, acMd);
- X *pcTo++ = '/';
- X pcTo = stradd(pcTo, acMu);
- X break;
- X case '\000':
- X fprintf(stderr, "%s: grade: command ends in %%?", progname);
- X exit(1);
- X default:
- X fprintf(stderr, "%s: grade: `%c\' unknown %% escape\n", progname, pcFrom[-1]);
- X exit(1);
- X }
- X } else {
- X *pcTo++ = *pcFrom++;
- X }
- X }
- X *pcTo = '\000';
- X
- X if (fVerbose) {
- X printf("%s\n", pcExec);
- X }
- X
- X if (fExec) {
- X system(pcExec);
- X }
- }
- X
- /* scan a directory for tar files to grade (ksb)
- X */
- scandiv(student)
- DIR *student;
- {
- X register struct direct *dpstudent;
- X register char *pcDot;
- X
- X while (NULL != (dpstudent = readdir(student))) {
- X if ('.' == dpstudent->d_name[0]) /* skip . */
- X continue;
- X strcpy(acMu, dpstudent->d_name);
- X if ((char *)0 == pcCmd) {
- X /* do nothing */;
- X } else if ((char *)0 != (pcDot = strrchr(acMu, '.')) && 'Z' == pcDot[1] && '\000' == pcDot[2]) {
- X *pcDot = '\000';
- X grade("zcat %u.Z >%u");
- X grade(pcCmd);
- X grade("rm -f %u");
- X *pcDot = '.';
- X } else {
- X grade(pcCmd);
- X }
- X }
- X closedir(student);
- X if ((char *)0 != pcSum) {
- X strcpy(acMu, "*");
- X grade(pcSum);
- X }
- }
- X
- /*
- X * scan the project directory and system off the commands (ksb)
- X * (with grade())
- X */
- void
- scan()
- {
- X register struct direct *dp;
- X register DIR *proj, *student;
- X
- X ceedee(acMp);
- X proj = opendir(".");
- X if (0 == strcmp(pcSections, acSectIgnore)) {
- X (void)strcpy(acMd, ".");
- X scandiv(proj);
- X } else {
- X while (NULL != (dp = readdir(proj))) {
- X if ('.' == dp->d_name[0]) /* dot entries skipped */
- X continue;
- X ceedee(dp->d_name);
- X (void)strcpy(acMd, dp->d_name);
- X student = opendir(".");
- X scandiv(student);
- X ceedee("..");
- X }
- X closedir(proj);
- X }
- X ceedee("..");
- }
- X
- /*
- X * get the words of wisdom from the user (ksb)
- X * strip leading white space, etc
- X */
- char *
- GetWord(pcBuf, iLen, pcDef)
- char *pcBuf, *pcDef;
- int iLen;
- {
- X register char *pcWhite, *pcCopy;
- X register int l;
- X
- X fflush(stdout);
- X pcBuf[0] = '\n';
- X if ((char *)0 == fgets(pcBuf, iLen, stdin))
- X return (char *)0;
- X pcWhite = pcBuf;
- X while (isspace(*pcWhite) && '\n' != *pcWhite)
- X ++pcWhite;
- X
- X pcCopy = pcBuf;
- X l = iLen;
- X while (l-- > 0 && '\n' != (*pcCopy = *pcWhite))
- X ++pcCopy, ++pcWhite;
- X
- X if (pcCopy == pcBuf)
- X (void)strncpy(pcBuf, pcDef, iLen);
- X else
- X *pcCopy = '\000';
- X return pcBuf;
- }
- X
- /*
- X * is a name a poor name for a course or subdirectory (ksb)
- X */
- int
- BadName(pc)
- char *pc;
- {
- X if ('\000' == *pc)
- X return 1;
- X for (; '\000' != *pc; ++pc) {
- X if (!isalnum(*pc) && *pc != '-' && *pc != '_')
- X return 1;
- X }
- X return 0;
- }
- X
- /*
- X * build the project managers data structures in the file system (ksb)
- X * also mail off a request to be added to the database
- X * we must be in the users home directory here!
- X * (Return the locked fd that keeps other projects blocked)
- X */
- int
- DoInit()
- {
- X auto char acBuf[MAXCHARS+1], acCmd[MAXPATHLEN+300],
- X acShort[MAXCOURSENAME+1], acDir[MAXSUBDIRNAME+1],
- X acGroup[MAXGROUPNAME+1], acDefGroup[MAXGROUPNAME+1],
- X acLong[MAXLONGNAME+1],
- X acTemp[MAXDIVSEC+1], acDiv[MAXDIVSEC+1],
- X acPrevExp[MAXYESNO+1], *pcComma;
- X auto struct group *pgr;
- X auto FILE *fpMail;
- X auto int fdLock, cnt, div, sec, fProc, fFound;
- X auto struct stat stDir;
- X extern struct group *getgrgid(), *getgrnam();
- X
- X setgrent();
- X if ((struct group *)0 == (pgr = getgrgid(getegid()))) {
- X fprintf(stderr, "%s: getgrgid: %d: %s\n", progname, getegid(), strerror(errno));
- X exit(1);
- X }
- X (void)strcpy(acDefGroup, pgr->gr_name);
- X
- X printf("\nEnabling %s to accept electronic submissions\n", ppwMe->pw_name);
- X printf("\n\
- Project allows other users to put files in your account. Please supply\n\
- the information requested below so that your account can be enabled to\n\
- accept submissions from turnin(1L). If you have questions or need help\n\
- ask a general consultant or send mail to \"%s\".\n", acMailAddr);
- X printf("\n\
- If you make a mistake you do not see a way to correct simply\n\
- finish this run and run the program again.\n");
- X
- X for (;;) {
- X printf("\nAre you sure you want to do this? [ny] ");
- X if ((char *)0 == GetWord(acBuf, MAXCHARS, "no"))
- X exit(0);
- X switch (acBuf[0]) {
- X case 'q':
- X case 'Q':
- X case 'N':
- X case 'n':
- X exit(0);
- X case 'y':
- X case 'Y':
- X break;
- X default:
- X continue;
- X }
- X break;
- X }
- X
- X if (0 != stat(".", & stDir)) {
- X fprintf(stderr, "%s: stat: .: %s\n", progname, strerror(errno));
- X exit(2);
- X }
- X if ((stDir.st_mode & 0755) != 0755) {
- X printf("\nYour home directory *must* be kept world readable so that\n");
- X printf("students and consultants can use turnin -v to see if they have\n");
- X printf("submitted anything.\n");
- X if (0 != chmod(".", stDir.st_mode | 0755)) {
- X fprintf(stderr, "%s: chmod: .: %s\n", progname, strerror(errno));
- X exit(2);
- X }
- X } else {
- X printf("\nYour home directory is already world readable. Please keep it that way\n");
- X printf("so that students and consultants can use turnin -v.\n");
- X }
- X
- X printf("\nHave you ever used %s to administer electronic submissions before? [ny] ", progname);
- X if ((char *)0 == GetWord(acPrevExp, MAXYESNO, "none"))
- X exit(0);
- X
- X do {
- X printf("\nA long name for a course might be something like \n\tProgramming in Mud\n");
- X printf("\nWhat is the long name of this course? ");
- X if ((char *)0 == GetWord(acLong, MAXLONGNAME, ""))
- X exit(0);
- X } while ('\000' == acLong[0]);
- X
- X for (;;) {
- X do {
- X printf("\nA short name for a course might be something like \n\tcs200\n");
- X printf("\nWhat is the short name of this course [%s]? ", acDefGroup);
- X
- X if ((char *)0 == GetWord(acShort, MAXCOURSENAME, acDefGroup))
- X exit(0);
- X } while ('\000' == acShort);
- X if (strlen(acShort) > MAXCOURSENAME) {
- X printf("Pick a shorter name, please.\n");
- X continue;
- X }
- X if (BadName(acShort)) {
- X printf("Course names cannot have special characters in them (except '-').\n");
- X continue;
- X }
- X break;
- X }
- X
- X pcCourse = acShort;
- X pcUid = (char *)0;
- X fFound = getcourse(acTurnbase);
- X if (fFound) {
- X printf("Course `%s' already exists owner %s.%s in %s", acShort, pcUid, pcGroup, pcDir);
- X if (0 != strcmp(acSectIgnore, pcSections))
- X printf("/{%s}", pcSections);
- X printf(".\n");
- X } else {
- X pcDir = acSubmit;
- X pcGroup = acDefGroup;
- X pcSections = (char *)0;
- X }
- X
- X for (;;) {
- X printf("\nAll submitted files will be under a special subdirectory in your account.\n");
- X printf("This directory will be world readable.\n");
- X printf("\nWhat do you want your submission directory named? [%s] ", pcDir);
- X if ((char *)0 == GetWord(acDir, MAXSUBDIRNAME, pcDir))
- X exit(0);
- X if (!BadName(acDir)) {
- X break;
- X }
- X printf("The directory name must be alpha-numeric.\n");
- X }
- X
- X printf("\nThe submitted files will not be group readable, but should have an\n");
- X printf("appropriate group none the less. For most people the default is fine.\n");
- X for (;;) {
- X printf("\nWhich group should the submitted files be in ? [%s] ", pcGroup);
- X if ((char *)0 == GetWord(acGroup, MAXGROUPNAME, pcGroup)) {
- X exit(0);
- X }
- X if ((struct group *)0 != (pgr = getgrnam(acGroup))) {
- X break;
- X }
- X printf("getgrname: %s: not found\n", acGroup);
- X }
- X
- X ceedee(acDir);
- X fdLock = OpenLock(); /* closed by exit or caller */
- X
- X sprintf(acCmd, "%s -s \"%s: request for \\`%s'\" %s", MAILX_PATH, progname, acShort, acMailAddr);
- X if (!fExec) {
- X if ((FILE *)0 == (fpMail = fopen("/dev/null", "w"))) {
- X fprintf(stderr, "%s: fopen: /dev/null: %s\n", progname, strerror(errno));
- X exit(1);
- X }
- X fProc = 0;
- X } else if ((FILE *)0 == (fpMail = popen(acCmd, "w"))) {
- X fprintf(stderr, "%s: cannot mail to (%s).\n", progname, strerror(errno));
- X if ((FILE *)0 == (fpMail = fopen(acDeadLetter, "a"))) {
- X exit(1);
- X }
- X fprintf(stderr, "%s: holding letter in %s\n", progname, acDeadLetter);
- X fProc = 0;
- X } else {
- X fProc = 1;
- X }
- X fprintf(fpMail, "Entry for `%s\' requested as follows:\n", acLong);
- X fprintf(fpMail, "\t%s%c%s%c%s%c%s", acShort, SEP, ppwMe->pw_name, SEP, acDir, SEP, acGroup);
- X
- X printf("\n\
- You can separate a large course into a few smaller parts for grading by\n\
- assigning division/section identifiers.\n\n");
- X printf("Three common naming conventions are listed below:\n");
- X printf("\tmorning\t\tafternoon\n");
- X printf("\t930scott\t230kevin\n");
- X printf("\td1s1\t\td2s1\n\n");
- X printf("Choose the type your students can best remember.\n");
- X printf("\nEnter the sections of your course one per line.\n");
- X printf("Use a dot (`.\') on a line by itself to stop.\n");
- X div = 1;
- X sec = 1;
- X cnt = 0;
- X pcComma = pcSections;
- X for (;;) {
- X if ((char *)0 == pcComma || '\000' == pcComma) {
- X sprintf(acTemp, "d%ds%d", div, sec);
- X } else {
- X register int i;
- X for (i = 0; i < MAXDIVSEC; ++i) {
- X if ('\000' == *pcComma) {
- X pcComma = (char *)0;
- X break;
- X }
- X if (',' == *pcComma) {
- X ++pcComma;
- X break;
- X }
- X acTemp[i] = *pcComma++;
- X }
- X acTemp[i] = '\000';
- X }
- X printf("section [%s] > ", acTemp);
- X if ((char *)0 == GetWord(acDiv, MAXDIVSEC, acTemp)) {
- X fprintf(fpMail, "\n\n!! Aborted !!\n\n");
- X (fProc ? pclose : fclose)(fpMail);
- X exit(0);
- X }
- X if ('.' == acDiv[0] && '\000' == acDiv[1]) {
- X if (0 == cnt) {
- X fprintf(fpMail, "%c%s", SEP, acSectIgnore);
- X ++cnt;
- X }
- X break;
- X }
- X if (BadName(acDiv)) {
- X printf("Divisions must have alpha-numeric names.\n");
- X continue;
- X }
- X fprintf(fpMail, "%c%s", (0 == cnt ? SEP : ','), acDiv);
- X ++cnt;
- X
- X /* make d<div>s<sec> easy to do for Purdue
- X */
- X if ('d' == acDiv[0] && isdigit(acDiv[1])) {
- X register char *pc;
- X div = atoi(acDiv+1);
- X if ((char *)0 != (pc = strchr(acDiv+2, 's')) && isdigit(pc[1])) {
- X sec = atoi(pc+1);
- X }
- X }
- X if (10 == ++sec) {
- X ++div;
- X sec = 1;
- X }
- X }
- X
- X printf("\nLastly, if you would like to be notified by phone when this is done\n");
- X printf("Please enter a phone number now: [No, Thanks] ");
- X (void) GetWord(acLong, MAXLONGNAME, "[No Phone Call Requested]");
- X
- X if (0 != strcmp(acDefGroup, acGroup)) {
- X fprintf(fpMail, "\n(default group was %s)", acDefGroup);
- X }
- X fprintf(fpMail, "\n\nPhone: %s\n", acLong);
- X fprintf(fpMail, "\nPrevious experience: %s", acPrevExp);
- X fprintf(fpMail, "\nDatabase file: `%s\'", acTurnbase);
- X if (fFound) {
- X fprintf(fpMail, "\nPrevious database line:\n\t%s:%s:%s:%s:%s", pcCourse, pcUid, pcDir, pcGroup, pcSections);
- X }
- X
- X (fProc ? pclose : fclose)(fpMail); /* works for fopen too, now */
- X
- X endgrent();
- X
- X printf("\nMail %s been sent to a superuser to finish the configuration.\n", fExec ? "has" : "would have" );
- X if (fExec) {
- X printf("You will be contacted via email or telephone when your account\n");
- X printf("is ready for use.\n");
- X }
- X return fdLock;
- }
- X
- X
- /*
- X * send the sysadmin mail telling her to remove us from the db (ksb)
- X */
- static void
- DoQuit()
- {
- X auto char acCmd[MAXPATHLEN+300];
- X auto int fProc;
- X auto FILE *fpMail;
- X
- X sprintf(acCmd, "%s -s \"%s: please delete \\`%s'\" %s", MAILX_PATH, progname, pcCourse, acMailAddr);
- X
- X if ((FILE *)0 == (fpMail = popen(acCmd, "w"))) {
- X fprintf(stderr, "%s: cannot open mail cmd (%s).\n", progname, strerror(errno));
- X if ((FILE *)0 == (fpMail = fopen(acDeadLetter, "a"))) {
- X exit(1);
- X }
- X fprintf(stderr, "%s: holding letter in %s\n", progname, acDeadLetter);
- X fProc = 0;
- X } else {
- X fProc = 1;
- X }
- X fprintf(fpMail, "\nPlease remove %s from the project database, `%s\'.\n", pcCourse, acTurnbase);
- X fprintf(fpMail, "\nThanks.\n");
- X (fProc ? pclose : fclose)(fpMail);
- X printf("\nMail %s been sent to a superuser to finish the job.\n", fExec ? "has" : "would have" );
- }
- X
- X
- static char acUsage[] = "[-cdehinqrvV] [-c course] [-G cmd] [-g cmd] [project]";
- static char *apcHelp[] = { /* a task help message */
- X "c course select which course to administer",
- X "d allow no submissions for a while",
- X "e allow submissions and change default project name",
- X "l allow submissions without changing default project",
- X "G cmd execute command for each division",
- X "g cmd execute command for all submitted files",
- X "h print this message",
- X "i initialize an account for submissions",
- X "n just print what would be done",
- X "o display a status line",
- X "q quit using this account for submissions",
- X "r delete a project",
- X "v output shell commands",
- X "V output version information",
- X (char *)0
- };
- static char *apcEsc[] = { /* an escape help message */
- X "cmd: may include any of %[htpdus%] which will be expanded before execution",
- X "%h home directory of instructor",
- X "%t turnin directory name",
- X "%p current project number",
- X "%d division/section identifier",
- X "%u current user identifier, or `*\'",
- X "%s full path (%h/%t/%p/%d/%u) to tar file",
- X "%% a %",
- X (char *)0
- };
- X
- /*
- X * read turnin data base (ksb)
- X * make a guess at the course
- X * which project, on? default?
- X * make tar file
- X * maybe display it
- X */
- int
- main(argc, argv)
- int argc;
- char **argv;
- {
- X static int fGiven = 0;
- X auto char acTop[MAXPATHLEN+1];
- X auto char acYes[MAXYESNO+1];
- X auto int i;
- X auto int iTemp, fdLock;
- X
- X umask(022);
- X
- X if ((char *)0 == (progname = strrchr(argv[0], '/')))
- X progname = argv[0];
- X else
- X ++progname;
- X
- X (void) setpwent();
- X if (NULL == (ppwMe = getpwuid(getuid()))) {
- X fprintf(stderr, "%s: getpwuid: %d: %s\n", progname, getuid(), strerror(errno));
- X exit(99);
- X }
- X
- X options(argc, argv);
- X if (What == INITIALIZE) {
- X printf("%s: initialize user %s for a course\n", progname, ppwMe->pw_name);
- X if (-1 == chdir(ppwMe->pw_dir)) {
- X fprintf(stderr, "%s: chdir: %s: %s\n", progname, ppwMe->pw_dir, strerror(errno));
- X exit(2);
- X }
- X fdLock = DoInit();
- X iProjnum = 0;
- X Projstatus[0] = OFF;
- X newprojects(0);
- X /* reply mail should include instructions for enabling projects
- X */
- X (void) close(fdLock);
- X exit(0);
- X }
- X
- X /* we change ppwMe below to reflect root becoming the user
- X */
- X if (NULL == (ppwMe = getpwuid(geteuid()))) {
- X fprintf(stderr, "%s: getpwuid: %d: %s\n", progname, geteuid(), strerror(errno));
- X exit(99);
- X }
- X if (0 == getcourse(acTurnbase)) {
- X if ((char *)0 == pcCourse)
- X fprintf(stderr, "%s: user %s not in database\n", progname, ppwMe->pw_name);
- X else
- X fprintf(stderr, "%s: course %s not in database\n", progname, pcCourse);
- X exit(1);
- X }
- X /* if we are root, become Prof here (which might be `lroot')
- X */
- X if ((struct passwd *)0 == (ppwMe = getpwnam(pcUid))) {
- X fprintf(stderr, "%s: getpwname: %s: %s\n", progname, pcUid, strerror(errno));
- X fprintf(stderr, "%s: no such course here\n", progname);
- X exit(1);
- X }
- X if (-1 == setuid(ppwMe->pw_uid)) {
- X fprintf(stderr, "%s: setuid: %s\n", progname, strerror(errno));
- X exit(20);
- X }
- X
- X if (0 == geteuid()) {
- X fprintf(stderr, "%s: run as root [ny]? ", progname);
- X fflush(stderr);
- X (void) GetWord(acYes, MAXYESNO, "no");
- X if ('y' != acYes[0] && 'Y' != acYes[0]) {
- X fprintf(stderr, "Aborted.\n");
- X exit(0);
- X }
- X }
- X sprintf(acTop, "%s/%s", ppwMe->pw_dir, pcDir);
- X ceedee(acTop);
- X
- X fdLock = OpenLock();
- X
- X getprojects();
- X
- X if (EOF != getarg(argc, argv)) {
- X fGiven = 1;
- X CheckChars("on the command line", optarg);
- X iTemp = search(optarg);
- X } else {
- X iTemp = iProjnum;
- X }
- X
- X if (-1 != iTemp) {
- X strcpy(acMp, aacProjnames[iTemp]);
- X }
- X
- X switch (What) {
- X case ENABLE:
- X if (-1 == iTemp) {
- X fprintf(stderr, "%s: no default project\n", progname);
- X exit(1);
- X }
- X iProjnum = iTemp;
- X Projstatus[iTemp] = ON;
- X Make(acMp);
- X newprojects(1);
- X break;
- X
- X case QUIT:
- X fprintf(stdout, "Are you sure you want to stop using %s [ny]? ", progname);
- X (void) GetWord(acYes, MAXYESNO, "no");
- X if ('y' != acYes[0] && 'Y' != acYes[0]) {
- X fprintf(stdout, "Aborted.\n");
- X exit(0);
- X }
- X for (i = 0; i < iProjcount; ++i) {
- X if (DELETE == Projstatus[i]) {
- X continue;
- X }
- X strcpy(acMp, aacProjnames[i]);
- X fprintf(stdout, "%s: remove project %s [ynq] ", progname, acMp);
- X (void) GetWord(acYes, MAXYESNO, "yes");
- X if ('q' == acYes[0] || 'Q' == acYes[0]) {
- X fprintf(stdout, "Aborted.\n");
- X exit(0);
- X }
- X if ('y' != acYes[0] && 'Y' != acYes[0]) {
- X continue;
- X }
- X Remove(aacProjnames[i]);
- X Projstatus[i] = DELETE;
- X }
- X for (i = 0; i < iProjcount; ++i) {
- X if (DELETE != Projstatus[i]) {
- X break;
- X }
- X }
- X if (i != iProjcount) {
- X printf("%s: not all projects removed, quit.\n", progname);
- X newprojects(1);
- X break;
- X }
- X ceedee("..");
- X if (fExec) {
- X DoQuit();
- X }
- X rm(pcDir);
- X break;
- X
- X case REMOVE:
- X if (-1 == iTemp) {
- X fprintf(stderr, "%s: no default project\n", progname);
- X exit(1);
- X }
- X fprintf(stdout, "Are you sure you want to delete all submissions for project %s [ny]? ", acMp);
- X (void) GetWord(acYes, MAXYESNO, "no");
- X if ('y' != acYes[0] && 'Y' != acYes[0]) {
- X fprintf(stdout, "Aborted.\n");
- X exit(0);
- X }
- X Remove(acMp);
- X Projstatus[iTemp] = DELETE;
- X newprojects(1);
- X break;
- X
- X case DISABLE:
- X if (-1 == iTemp) {
- X fprintf(stderr, "%s: no default project\n", progname);
- X exit(1);
- X }
- X Projstatus[iTemp] = OFF;
- X newprojects(1);
- X break;
- X
- X case GRADE:
- X if (-1 == iTemp) {
- X fprintf(stderr, "%s: no default project\n", progname);
- X exit(1);
- X }
- #if HAVE_NICE
- X nice(2);
- #else /* vax */
- X setpriority(PRIO_PROCESS, getpid(), 2);
- #endif /* machine */
- X scan();
- X break;
- X
- X case OUTPUT:
- X fprintf(stdout, "%s: user: %s.%s, course: %s, subdirectory: %s\n", progname, ppwMe->pw_name, pcGroup, pcCourse, pcDir);
- X for (i = 0; i < iProjcount; ++i) {
- X fprintf(stdout, "%s: project %-8s (%s)\n", progname, aacProjnames[i], (OFF == Projstatus[i] ? "off" : iProjnum == i ? "default" : "on"));
- X }
- X break;
- X
- X case VERSION:
- X printf("%s: %s\n", progname, RCSId);
- X printf("%s: default directory name: %s\n", progname, acSubmit);
- X break;
- X
- X case LATE:
- X if (-1 == iTemp) {
- X fprintf(stderr, "%s: no default project\n", progname);
- X exit(1);
- X }
- X if (iTemp == iProjnum) {
- X iProjnum = -1;
- X }
- X Projstatus[iTemp] = ON;
- X Make(acMp);
- X newprojects(1);
- X break;
- X
- X case HELP:
- X fprintf(stdout, "%s: usage %s\n", progname, acUsage);
- X for (i = 0; apcHelp[i]; ++i) {
- X fprintf(stdout, "%s\n", apcHelp[i]);
- X }
- X if (fVerbose) {
- X for (i = 0; apcEsc[i]; ++i) {
- X fprintf(stdout, "%s\n", apcEsc[i]);
- X }
- X }
- X break;
- X
- X case UNKNOWN:
- X if (fGiven) {
- X Make(acMp);
- X newprojects(1);
- X break;
- X }
- X /*fallthrough*/
- X default:
- X fprintf(stderr, "%s: usage %s\n", progname, acUsage);
- X break;
- X }
- X
- X (void) endpwent();
- X (void) close(fdLock);
- X exit(0);
- }
- Purdue
- chmod 0444 project/project.c ||
- echo 'restore of project/project.c failed'
- Wc_c="`wc -c < 'project/project.c'`"
- test 32572 -eq "$Wc_c" ||
- echo 'project/project.c: original size 32572, current size' "$Wc_c"
- fi
- exit 0
-
- exit 0 # Just in case...
-